﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.ServiceModel;
using System.Threading;
using System.IO;

namespace Teenus {

    /// <summary>
    /// Teenuse ja kasutajaliidese haldamise klass.
    /// </summary>
    static class Program {

        private static Form1 kasutajaliides;
        private static ServiceHost host;
        private static Thread logger;
        private static List<String> logi = new List<string>();

        /// <summary>
        /// Tõmbab käima kasutajaliidese ja teenuse.
        /// </summary>
        [STAThread]
        static void Main() {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            kasutajaliides = new Form1();

            //TEENUSE LÕPLIKUS VERSIOONIS ALLJÄRGNEV RIDA EEMALDADA:
            startService();

            Application.Run(kasutajaliides);            
        }


        /// <summary>
        /// Üritab teenust käivitada. Kui ei õnnestu, siis näitab kasutajaliideses viga.
        /// </summary>
        internal static void startService() {
            if (host == null) {
                try {
                    Uri baseURI = new Uri("http://localhost:43678/Kohvikuteenus");
                    host = new ServiceHost(typeof(Service), baseURI);
                    host.AddServiceEndpoint(typeof(IService), new WSHttpBinding(), baseURI);
                    logger = new Thread(new ThreadStart(Program.startLogger));
                    logger.Start();
                    host.Open();
                    writeToLog(host.State.ToString());
                }
                catch (Exception e) {
                    writeToLog("Error while starting service:" + e.ToString());
                    kasutajaliides.setLabelText("Faulted");
                    return;
                }
                kasutajaliides.setLabelText(host.State.ToString());                
            }
        }


        /// <summary>
        /// Üritab teenust sulgeda, Kui ei õnnestu, siis näitab kasutajaliideses viga.
        /// </summary>
        internal static void stopService() {
            try {
                if (host != null)
                    if (host.State != CommunicationState.Closed)
                        host.Close();
                        logger.Abort();
                        kasutajaliides.setLabelText(host.State.ToString());
                        writeToLog(host.State.ToString());
                        host = null;
            }
            catch (Exception) {
                //EI õnnestunud teenust sulgeda
                writeToLog("Could not close service");
            }
        }


        /// <summary>
        /// Kirjutab logisse teate.
        /// </summary>
        /// <param name="p"></param>
        internal static void writeToLog(string p) {
            String mess = DateTime.Now + ": " + p + "\r\n";
            kasutajaliides.addText(mess);
            lock (logi) {
                logi.Add(mess);
            }            
        }


        /// <summary>
        /// Kirjutab iga sekundi tagant logi faili.
        /// </summary>
        internal static void startLogger() {
            TextWriter wr = new StreamWriter("log.txt", true);

            try { 
                while (true) { 
                    Thread.Sleep(1000);
                
                    if (logi.Count != 0) {
                        lock (logi) {
                            foreach (String s in logi) {
                                wr.WriteLine(s);
                            }
                            logi.Clear();
                        }
                        wr.Flush();
                    }
                
                }   //END while
            } catch(ThreadAbortException) {
                lock (logi) {
                    foreach (String s in logi) {
                        wr.WriteLine(s);
                    }
                }
                wr.Flush();
                wr.Close();
            }

        }       //END startLogger()

    }
}
